/*
 *  Copyright (c) 2010 Andy Aspell-Clark
 *
 *  Permission is hereby granted, free of charge, to any person
 *  obtaining a copy of this software and associated documentation
 *  files (the "Software"), to deal in the Software without
 *  restriction, including without limitation the rights to use,
 *  copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following
 *  conditions:
 *
 *  The above copyright notice and this permission notice shall be
 *  included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *  OTHER DEALINGS IN THE SOFTWARE.
 */
package uk.org.aspellclark.agenedb.controller;

import java.io.File;

import uk.org.aspellclark.gedcom.model.records.FamRecord;
import uk.org.aspellclark.gedcom.model.records.IndividualRecord;
import android.content.Context;
import android.util.Log;

import com.bitsetters.android.passwordsafe.DBHelper;
import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.config.Configuration;

/**
 * @author     andy
 * @created    29 April 2010
 */
public class Db4oController {

	private final static String DB4OFILENAME = "AGeneDB.db4o";

	/**  Description of the Field */
	public ObjectContainer db;

	private Context context;

	/**
	 * Constructor for the Db4oController object
	 *
	 * @param  ctx  Description of the Parameter
	 */
	public Db4oController(Context ctx) {
		super();
		this.context = ctx;
	}

	/**
	 *  commit any pending database changes and 
	 *  close the connection to the database.
	 */
	public void closeDatabase() {
		Log.w("DbController", "closing database");
		this.db.commit();
		this.db.flush();
		this.db.close();
		this.db = null;
	}

	public String db4oDBFullPath(Context ctx) {
		return ctx.getDir("data", 0) + "/" + DB4OFILENAME;
	}

	private Configuration dbConfig() {
		Configuration config = Db4o.newConfiguration();

		String xrefFieldName = "xref";

		//Index entries by Id

		config.objectClass(IndividualRecord.class).objectField(xrefFieldName).indexed(true);
		config.objectClass(FamRecord.class).objectField(xrefFieldName).indexed(true);
		config.objectClass(Note.class).objectField(xrefFieldName).indexed(true);
		config.objectClass(ChangeDate.class).objectField(xrefFieldName).indexed(true);

		//Configure proper activation + update depth
		//TODO

		config.testConstructors(true);
		config.optimizeNativeQueries(true);
		config.weakReferences(false);

		return config;
	}

	public void deleteDatabase() {
		File dbFile = new File(this.db4oDBFullPath(this.context));
		dbFile.delete();
	}

	@Override
	protected void finalize() throws Throwable {
		try {
			this.closeDatabase();
		} finally {
			super.finalize();
		}
	}

	/**
	 *  open a connection to the database.
	 */
	public ObjectContainer openDatabase() {
		Log.w("DbController", "opening database");
		try {
			if (this.db == null || this.db.ext().isClosed()) {
				this.db = Db4o.openFile(this.dbConfig(), this.db4oDBFullPath(this.context));
			}
			return this.db;
		} catch (Exception e) {
			Log.e(DBHelper.class.getName(), e.toString());
			return null;
		}
	}

}
